package com.rexpress.xposed.malwarebuster;

import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import de.robv.android.xposed.*;

public class MalwareBusterModule implements IXposedHookZygoteInit, IXposedHookLoadPackage {

    public static final String this_package = MalwareBusterModule.class.getPackage().getName();

    public static XSharedPreferences prefs;

    public void XLog(String str)
    {
        XposedBridge.log(this.this_package + " : " + str);
    }

    @Override
    public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {
        loadPrefs();
        XLog("XSharedPreference loaded");
    }

    public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {

        //Skip system app
        if (lpparam.appInfo != null && (lpparam.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
            return;
        }

        //Hook active status
        if (this_package.equals(lpparam.packageName)) {
            XposedHelpers.findAndHookMethod(this_package + ".MainActivity",
                    lpparam.classLoader, "isModActive", XC_MethodReplacement.returnConstant(true));
            return;
        }

        //Reload SharedPreference
        prefs.reload();

        boolean glbHookStatus = prefs.getBoolean(Common.GLOBALHOOK, false);

        //Global hook
        if (glbHookStatus) {
            XLog("Global Hook: " + lpparam.packageName);
        }
        else { //Individual hook
            boolean needHook = prefs.getBoolean(lpparam.packageName, false);

            if (!needHook)
                return;

            XLog("Need Hook: " + lpparam.packageName);
        }

        //http://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)
        //https://android.googlesource.com/platform/frameworks/base/+/4f868ed/core/java/android/app/ApplicationPackageManager.java
		//the theory is simple, the most important job is to detact, show and record the components which you want to forbit
        try {
            XposedHelpers.findAndHookMethod("android.app.ApplicationPackageManager", lpparam.classLoader, "setComponentEnabledSetting", ComponentName.class, int.class, int.class, new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    XLog("setComponentEnabledSetting hooked for " + param.args[0].toString());
                    param.args[1] = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
                }
            });

        } catch (Exception E) {
            XLog(E.toString());
        }

    }

    private static void loadPrefs() {
        prefs = new XSharedPreferences(Common.MY_PACKAGE_NAME, Common.PREFS);
        prefs.makeWorldReadable();
    }
}
